#!/usr/bin/env python
# encoding: UTF-8

"""Upravená verze SimpleXMLRPCServer, obsahuje debugging log, mapování chyb
na faultCode. Z faultCode zjistíme skutečnou vyjímku jednoduše:
exception = error.fault_codes[faultCode]"""

__version__ = "$Revision: 12 $"


import SimpleXMLRPCServer as S
import error
import sys
import xmlrpclib
from xmlrpclib import Fault

class XMLRPCServer(S.SimpleXMLRPCServer):
    """Upravená verze SimpleXMLRPCServer, obsahuje debug logging a mapování 
    chyb na faultCode
    logfile je file-like object, do kterého se zapisuje, pokud debug_logging
    je True"""
    debug_logfile = None
    debug_logging = True

    def debug_log(self, data):
        """Log some data to communication.log, overwriting the old with
        each new instance of server (only for debugging)"""
        if not self.debug_logging:
            return
        if self.debug_logfile is None:
            self.debug_logfile = open("communication.log", "w")
        self.debug_logfile.write(data)
        self.debug_logfile.write("\n\n")
        self.debug_logfile.flush()
    
    def _marshaled_dispatch(self, data, dispatch_method = None):
        """Dispatches an XML-RPC method from marshalled (XML) data.

        XML-RPC methods are dispatched from the marshalled (XML) data
        using the _dispatch method and the result is returned as
        marshalled data. For backwards compatibility, a dispatch
        function can be provided as an argument (see comment in
        SimpleXMLRPCRequestHandler.do_POST) but overriding the
        existing method through subclassing is the prefered means
        of changing method dispatch behavior.
        """
        self.debug_log(data)
        try:
            params, method = xmlrpclib.loads(data)

            # generate response
            if dispatch_method is not None:
                response = dispatch_method(method, params)
            else:
                response = self._dispatch(method, params)
            # wrap response in a singleton tuple
            response = (response,)
            response = xmlrpclib.dumps(response, methodresponse=1,
                                       allow_none=self.allow_none, 
                                       encoding=self.encoding)
        except Fault, fault:
            response = xmlrpclib.dumps(fault, allow_none=self.allow_none,
                                       encoding=self.encoding)
        except:
            # report exception back to server
            exc_type, exc_value, exc_tb = sys.exc_info()
            try:
                fault_code = error.fault_codes.index(exc_type)
            except ValueError:
                fault_code = -1
            response = xmlrpclib.dumps(
                xmlrpclib.Fault(fault_code, "%s.%s:%s" % (exc_type.__module__, 
                                                exc_type.__name__, exc_value)),
                encoding=self.encoding, allow_none=self.allow_none,
                )

        self.debug_log(response)
        return response
